﻿using System.Linq;
using System.Web.Mvc;
using ContactManagement.Models;
using ContactMvc4TB.Helpers.CategoryManagement;
using ContactMvc4TB.Helpers.RightsManagement;
using EFDataModel;
using EFDataModel.Enums;

namespace ContactManagement.Controllers
{
    /// <summary>
    /// Auf den Administrationscontroller hat nur der Administrator oder Superuser Zugriff.
    /// </summary>
    [CustomAuthorize]
    public partial class AdministrationController : Controller
    {
        #region Public Views
        /// <summary>
        /// Anzeigen der UserCategories
        /// GET: /Administration/Categories/UserCategoryList
        /// </summary>
        public ActionResult CategoriesList(string error)
        {
            CategoriesListModel categoriesList = new CategoriesListModel();
            //Durch eine Extra Rounte in der Global.asax, wird diese Funktion immer aufgerufen wenn, es sich um das Anzeigen von Kategorien handelt.
            //Daher muss erst geprüft werden welche Kategorie bearbeitet werden soll und dann kann der entsprechende View zurück gegeben werden.

            //Da im Datenmodell alle Kategorien von der selben Basisklasse ableiten, kann hier auch die gleiche Seite für alle Kategorien verwendet werden.
            //Ermitteln der aktuellen Kategorie die angezeigt werden soll
            EFCategoryTypes currentCategory = WebCategory.CurrentCategory(this);

            switch (currentCategory)
            {
                case EFCategoryTypes.UserCategory:
                    //Anzeigen der UserKategorien
                    categoriesList.Categories = from eUserCategory in CurrentHttpContext.GetDataModel().EFCategoryMenge.AsNoTracking().OfType<UserCategory>() select eUserCategory;
                    break;

                case EFCategoryTypes.UserGroups:
                    //Anzeigen UserGruppen, welche nichts anderes als Kategorien sind.
                    categoriesList.Categories = from efGroup in CurrentHttpContext.GetDataModel().EFCategoryMenge.AsNoTracking().OfType<UserGroup>() select efGroup;
                    break;

                case EFCategoryTypes.UserRights:
                    //Anzeigen UserRights, welche nichts anderes als Kategorien sind.
                    categoriesList.Categories = from eUserRight in CurrentHttpContext.GetDataModel().EFCategoryMenge.AsNoTracking().OfType<UserRight>() select eUserRight;
                    break;

                case EFCategoryTypes.DynamicDataTypeCategory:
                    categoriesList.Categories = from eDynamicDataTypeCategory in CurrentHttpContext.GetDataModel().EFCategoryMenge.AsNoTracking().OfType<DynamicDataTypeCategory>() select eDynamicDataTypeCategory;
                    break;
            }

            //Auf den passenden View für die Kategorie verweisen
            return View(categoriesList);
        }

        /// <summary>
        /// Erstellen einer neuen Kategorie
        /// GET: /Administration/CategoryName/CategoriesAdd
        /// </summary>
        public ActionResult CategoriesAdd()
        {
            CategoriesAddModel categoriesAddModel = new CategoriesAddModel();
            return View(categoriesAddModel);
        }

        /// <summary>
        /// Da im Datenmodell alle Kategorien von der selben Basisklasse ableiten, kann hier auch die gleiche Seite für alle Kategorien verwendet werden.
        /// </summary>
        [HttpPost]
        public ActionResult CategoriesAdd(CategoriesAddModel model)
        {
            if (ModelState.IsValid)
            {
                //Ermitteln der aktuellen Kategorie
                EFCategoryTypes currentCategory = WebCategory.CurrentCategory(this);
                switch (currentCategory)
                {
                    case EFCategoryTypes.UserGroups:
                        //Erstellen einer UserGruppe
                        WebUserGroups.UserGroups(this).Add(model);
                        break;
                    case EFCategoryTypes.UserCategory:
                        //Erstellen einer UserKategorie
                        WebUserCategories.UserCategories(this).Add(model);
                        break;
                    case EFCategoryTypes.DynamicDataTypeCategory:
                        WebDynamicDataTypeCategories.DynamicDataTypeCategories(this).Add(model);
                        break;
                }

                //auf die Übersicht verweisen, wo der Eintrag hinzugefügt wurde.
                return RedirectToRoute(RouteNames.Categories.ToString(), URLBuilder.ShowCategoriesList(currentCategory));
            }

            return View(model);
        }

        /// <summary>
        /// Löschen der Kategorie Id die im Link übergeben wird
        /// </summary>
        /// <param name="id">Die Kategorie Id die gelöscht werden soll</param>
        /// <returns>verweißt wieder auf die Liste mit den Einträgen.</returns>
        public ActionResult CategoriesDelete(int id)
        {
            //Ermitteln der aktuellen Kategorie
            EFCategoryTypes currentCategory = WebCategory.CurrentCategory(this);

            switch (currentCategory)
            {
                case EFCategoryTypes.UserGroups:
                    //Löschen einer UserGruppe
                    WebUserGroups.UserGroups(this).Delete(id);
                    break;
                case EFCategoryTypes.UserCategory:
                    //Löschen einer UserKategorie
                    WebUserCategories.UserCategories(this).Delete(id);
                    break;
                case EFCategoryTypes.DynamicDataTypeCategory:
                    WebDynamicDataTypeCategories.DynamicDataTypeCategories(this).Delete(id);
                    break;
            }

            //auf die Übersicht verweisen, wo der Eintrag entfernt werden sollte.
            return RedirectToRoute(RouteNames.Categories.ToString(), URLBuilder.ShowCategoriesList(currentCategory));
        }

        /// <summary>
        /// Beim Erstellen des Views für das Bearbeiten der aktuellen Kategorie, wird die ID in der URL übergeben
        /// </summary>
        /// <param name="id">die KategorieID die bearbeitet werden soll.</param>
        /// <returns>View zum Bearbeiten eines Kategorieeintrages</returns>
        public ActionResult CategoriesEdit(int id)
        {
            CategoriesAddModel categoriesAddModel = null;

            //Ermitteln der aktuellen Kategorie
            EFCategoryTypes currentCategory = WebCategory.CurrentCategory(this);
            switch (currentCategory)
            {
                case EFCategoryTypes.UserGroups:
                    //Erstellen einer UserGruppe
                    categoriesAddModel = WebUserGroups.UserGroups(this).Edit(id);
                    break;
                case EFCategoryTypes.UserCategory:
                    //Erstellen einer UserKategorie
                    categoriesAddModel = WebUserCategories.UserCategories(this).Edit(id);
                    break;
                case EFCategoryTypes.DynamicDataTypeCategory:
                    categoriesAddModel = WebDynamicDataTypeCategories.DynamicDataTypeCategories(this).Edit(id);
                    break;
            }

            if (categoriesAddModel != null)
            {
                //auf die Übersicht verweisen, wo der Eintrag bearbeitet werden kann.
                return View(categoriesAddModel);
            }

            //Auf die Startseite verweisen, wenn nach einer Kategorie gefragt wird die nicht existiert.
            return RedirectToAction(EActionHome.Index.ToString(), EControllers.Home.ToString());
        }

        /// <summary>
        /// Ändern (speichern) der eingegebenen Daten aus der Oberfläche für die Kategorie
        /// </summary>
        /// <param name="id">Die Kategorie Id die bearbeitet werden soll</param>
        [HttpPost]
        public ActionResult CategoriesEdit(int id, CategoriesAddModel model)
        {
            if (ModelState.IsValid)
            {
                //Ermitteln der aktuellen Kategorie
                EFCategoryTypes currentCategory = WebCategory.CurrentCategory(this);
                switch (currentCategory)
                {
                    case EFCategoryTypes.UserGroups:
                        //Bearbieten einer UserGruppe
                        WebUserGroups.UserGroups(this).Edit(id, model);
                        break;
                    case EFCategoryTypes.UserCategory:
                        //Bearbieten einer UserKategorie
                        WebUserCategories.UserCategories(this).Edit(id, model);
                        break;
                    case EFCategoryTypes.DynamicDataTypeCategory:
                        WebDynamicDataTypeCategories.DynamicDataTypeCategories(this).Edit(id, model);
                        break;
                }

                //auf die Übersicht verweisen, mit den UserGroups
                return RedirectToRoute(RouteNames.Categories.ToString(), URLBuilder.ShowCategoriesList(currentCategory));
            }

            return View(model);
        }

        /// <summary>
        /// Bearbeiten der UserGruppe, welche Member ihr angehören und welche ihr nicht angehören.
        /// GET: /Administration/Categories/UserGroups/UserGroupsAddUser/23
        /// </summary>
        /// <param name="id">GroupId zu der User hinzugefügt werden sollen</param>
        public ActionResult UserGroupsShowUsers(int id)
        {
            //Das Model mit Daten füllen
            UserGroupUsersListModel userGroupUsersListModel = WebUserGroups.UserGroups(this).UsersByUserGroup(id);
            return View(userGroupUsersListModel);
        }

        /// <summary>
        /// Das Hinzufügen eines Users zu einer Usergruppe wird nicht per Post Eingabe gemacht sondern auch wieder direkt über einen Link.
        /// </summary>
        /// <param name="id">die GroupId um die es sich handelt</param>
        /// <param name="userId">die UserId die der Gruppe hinzugefügt werden soll</param>
        /// <returns>Verweißt wieder auf die Liste wo die Member der Gruppe aufgelistet sind</returns>
        public ActionResult UserGroupsShowUsersAdd(int id, int userId)
        {
            //der Gruppe den User hinzufügen
            WebUserGroups.UserGroups(this).AddUserToGroup(id, userId);
            //Wieder auf die Seite verweisen, wo die User der Gruppe aufgelistet werden
            return RedirectToRoute(RouteNames.Categories.ToString(), URLBuilder.UserGroupsShowUsers(id));
        }

        /// <summary>
        /// Das Löschen eines Users aus einer Usergruppe wird nicht per Post Eingabe gemacht sondern auch wieder direkt über einen Link.
        /// </summary>
        /// <param name="id">die GroupId um die es sich handelt</param>
        /// <param name="userId">die UserId die aus der Gruppe gelöscht werden soll</param>
        /// <returns>Verweißt wieder auf die Liste wo die Member der Gruppe aufgelistet sind</returns>
        public ActionResult UserGroupsShowUsersDelete(int id, int userId)
        {
            //aus der Gruppe den User entfernen
            WebUserGroups.UserGroups(this).DeleteUserFromGroup(id, userId);
            //Wieder auf die Seite verweisen, wo die User der Gruppe aufgelistet werden
            return RedirectToRoute(RouteNames.Categories.ToString(), URLBuilder.UserGroupsShowUsers(id));
        }

        /// <summary>
        /// Anzeigen des übergebenen Userrights und welche Mitglieder das Userright hat und welche nicht.
        /// </summary>
        /// <param name="id">UserRight Id zu der die Member rausgesucht werden</param>
        public ActionResult UserRightsShowUsers(int id)
        {
            UserRightUsersListModel userGroupUsersListModel = WebUserRights.UserRights(this).UserRightsByUserRightId(id);
            if (userGroupUsersListModel != null)
            {
                return View(userGroupUsersListModel);
            }

            //Auf die Startseite verweisen, wenn nach einer Kategorie gefragt wird die nicht existiert.
            return RedirectToAction(EActionHome.Index.ToString(), EControllers.Home.ToString());
        }

        /// <summary>
        /// Hinzufügen des rechts zur übergenenen UserId
        /// </summary>
        /// <param name="id">RechteDb Id die dem User hinzugefügt werden soll</param>
        /// <param name="userId">UserId dem das übergenene Recht hinzugefügt werden soll</param>
        public ActionResult UserRightsShowUsersAdd(int id, int userId)
        {
            WebUserRights.UserRights(this).AddUserRightToUser(userId, id);
            //Wieder auf die Seite verweisen, wo die User der Gruppe aufgelistet werden
            return RedirectToRoute(RouteNames.Categories.ToString(), URLBuilder.UserRightsShowUsers(id));
        }

        /// <summary>
        /// Entfernen des Rechts zur übergebenen UserId
        /// </summary>
        /// <param name="id">RechteDb Id die vom User entfernt werden soll</param>
        /// <param name="userId">UserId der das Recht entfernt werden soll</param>
        public ActionResult UserRightsShowUsersDelete(int id, int userId)
        {
            WebUserRights.UserRights(this).DeleteUserRightFromUser(userId, id);
            //Wieder auf die Seite verweisen, wo die User der Gruppe aufgelistet werden
            return RedirectToRoute(RouteNames.Categories.ToString(), URLBuilder.UserRightsShowUsers(id));
        }

        /// <summary>
        /// Anzeigen der Rechte die der Gruppe zugewiesen sind
        /// </summary>
        /// <param name="id">Die gruppe von der die Rechte angezeigt werden sollen</param>
        public ActionResult UserGroupsShowRights(int id)
        {
            //Laden der Modeldaten um anzuzeigen welche Rechte für die Gruppe gesetzt sind oder nicht.
            GroupRightListModel groupRightListModel = WebUserGroups.UserGroups(this).RightsByUserGroup(id);
            return View(groupRightListModel);
        }

        /// <summary>
        /// Das Recht zur Gruppe hinzufügen
        /// </summary>
        /// <param name="rightId">RechteId die zur Gruppe hinzugefügt werden soll</param>
        /// <param name="id">Die gruppe der das neue Recht hinzugefügt werden soll</param>
        public ActionResult UserGroupsShowRightsAdd(int id, int rightId)
        {
            WebUserGroups.UserGroups(this).AddRightToGroup(rightId, id);
            //Wieder auf die Seite verweisen, wo die UserRights der Gruppe aufgelistet werden
            return RedirectToRoute(RouteNames.Categories.ToString(), URLBuilder.GroupShowRights(id));
        }

        /// <summary>
        /// Das recht von der Gruppe entfernen 
        /// </summary>
        /// <param name="rightId">RechteId die der Gruppe hinzugefügt werden soll</param>
        /// <param name="id">die GruppenId die der Gruppe hinzugefügt werden soll</param>
        public ActionResult UserGroupsShowRightsDelete(int id, int rightId)
        {
            WebUserGroups.UserGroups(this).DeleteRightFromGroup(rightId, id);
            //Wieder auf die Seite verweisen, wo die UserRights der Gruppe aufgelistet werden
            return RedirectToRoute(RouteNames.Categories.ToString(), URLBuilder.GroupShowRights(id));
        }
        #endregion
    }
}
